package fun.yao.common.monitor;

import fun.yao.common.Constant;
import fun.yao.common.db.ConnManager;
import fun.yao.common.db.ConnPool;
import fun.yao.common.monitor.info.*;
import fun.yao.common.nio.GessSocketChannel;
import fun.yao.common.queue.AFileCacheQueue;
import fun.yao.common.queue.CycleQueue;
import fun.yao.common.uitls.ConfigUtil;
import fun.yao.common.uitls.LogUtil;

import java.math.BigDecimal;
import java.net.Socket;
import java.util.Collection;
import java.util.Enumeration;
import java.util.Iterator;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

/**
 * 后台服务监控线程
 * 监控内容包括：
 *  1. 广播服务的在线客户数
 *  2. 线程情况
 *  3. 网络流量
 *  4. 交易业务的执行情况
 *  5. 检查死锁
 *  6. 检查内存缓存数据
 * @author aps-csl 2008.11.28
 */
public class MonitorThread extends Thread implements IMonitor
{
    /** 监控信息输出级别：简单 */
    public static final int INFO_LEVEL_SIMPLE = 0;
    /** 监控信息输出级别: 详细 */
    public static final int INFO_LEVEL_DETAIL = 1;

    /** 监控信息输出频率（单位：秒 ) */
    private static int iPrintFrequencyTime = ConfigUtil.getConfigByInt("MONITOR_PRINT_FREQUENCY_TIME",30*60);
    /** 监控信息级别 */
    private static int iMonitorInfoLevel   = ConfigUtil.getConfigByInt("MONITOR_INFO_LEVEL",INFO_LEVEL_SIMPLE);
    /** 是否检查循环调用情况 */
    private static boolean bIsRunCycleMonitor = ConfigUtil.getConfigByBoolean("MONITOR_RUN_CYCLE",false);
    /** 内存使用情况打印的间隔时间（秒）*/
    private static int iPrintMemoryTime = ConfigUtil.getConfigByInt("MONITOR_PRINT_MEMORY_TIME", 10*60);

    /** 垃圾内存回收间隔时间(分钟) */
    private static int iRunSystemGcInvTime = ConfigUtil.getConfigByInt("RUN_SYSTEM_GC_INV_TIME", 120);


    /** 被监控的的Map集合 */
    private final static ConcurrentHashMap<String,Map> sMaps = new ConcurrentHashMap<String,Map>();
    /** 被监控的Collection 集合 */
    private final static ConcurrentHashMap<String,Collection> sCollections = new ConcurrentHashMap<String,Collection>();
    /** 被监控的循环 */
    private final static ConcurrentHashMap<String,Long> sCycles = new ConcurrentHashMap<String,Long>();
    /** 被监控的线程 */
    private final static ConcurrentHashMap<String,Thread> sThreads = new ConcurrentHashMap<String,Thread>();
    /** 被监控的Socket */
    private final static ConcurrentHashMap<String,GessSocketChannel> sSockets = new ConcurrentHashMap<String,GessSocketChannel>();
    /** 被监控的普通Socket */
    private final static ConcurrentHashMap<String,Socket> sNormalSockets = new ConcurrentHashMap<String,Socket>();
    /** 被监控的文件队列 */
    private final static ConcurrentHashMap<String,AFileCacheQueue> sFileCacheQueues = new ConcurrentHashMap<String,AFileCacheQueue>();
    /** 被监控循环的队列 */
    private final static ConcurrentHashMap<String,CycleQueue<?>> sCycleQueues = new ConcurrentHashMap<String,CycleQueue<?>>();

    /** 是否动行 */
    private boolean bIsRun = true;

    /** 上一次运行系统内存回收的时间 */
    private static long lastGcTime = System.currentTimeMillis();

    /** 上一次监控时间 */
    private static long lastTime = System.currentTimeMillis();

    /** 上次读取配置时间 */
    private static long lastReadTime = System.currentTimeMillis();

    /** 上次打印内存情况的时间 */
    private static long lastPrintMemory = System.currentTimeMillis();

    /** 当前监控时间 */
    private static long currTime = 0;

    /** 端口连接数量 key=端口 value:key=TotalNum CurrNum 总连接数、当前连接数*/
    private final static ConcurrentHashMap<String,ConcurrentHashMap<String, Long>> sConnNum = new ConcurrentHashMap<String,ConcurrentHashMap<String,Long>>();

    /**启动时间*/
    private static long startTime = System.currentTimeMillis();

    public MonitorThread()
    {

    }


    /**
     * 线程方法
     */
    public void run()
    {
        String sName = "MonitorThread";
        StringBuilder sbOut = new StringBuilder();
        startTime = System.currentTimeMillis();

        while ( bIsRun )
        {
            try
            {
                MonitorThread.addCycleInvoke(sName);
                Thread.sleep(500);
                currTime = System.currentTimeMillis();

                //每10秒，重新读取配置信息
                if ( ( currTime - lastReadTime ) > 10*1000 )
                {
                    //重新读取配置信息
                    iPrintFrequencyTime = ConfigUtil.getConfigByInt("MONITOR_PRINT_FREQUENCY_TIME",30*60);
                    iMonitorInfoLevel = ConfigUtil.getConfigByInt("MONITOR_INFO_LEVEL",INFO_LEVEL_SIMPLE);
                    bIsRunCycleMonitor = ConfigUtil.getConfigByBoolean("MONITOR_RUN_CYCLE",false);
                    iRunSystemGcInvTime = ConfigUtil.getConfigByInt("RUN_SYSTEM_GC_INV_TIME", 120);
                    iPrintMemoryTime = ConfigUtil.getConfigByInt("MONITOR_PRINT_MEMORY_TIME", 10*60);
                }

                //每60秒，打印一次内存使用情况
                if ( ( currTime - lastPrintMemory) > iPrintMemoryTime * 1000 )
                {
                    Runtime runtime = Runtime.getRuntime();
                    BigDecimal bd_mem1 = new BigDecimal(String.valueOf((runtime.totalMemory()-runtime.freeMemory())/1024.0/1024.0)).setScale(2,BigDecimal.ROUND_HALF_UP);
                    LogUtil.writeSystemLog(Constant.NOTICE, "内存使用情况监控：内存占用[" + bd_mem1.toString() + "]M");
                    lastPrintMemory = currTime ;
                }

                //每半个小时运行一次系统内存回收
                if ( currTime - lastGcTime > iRunSystemGcInvTime * 60 * 1000 )
                {
                    Runtime runtime = Runtime.getRuntime();
                    BigDecimal bd_mem1 = new BigDecimal(String.valueOf((runtime.totalMemory()-runtime.freeMemory())/1024.0/1024.0)).setScale(2,BigDecimal.ROUND_HALF_UP);
                    LogUtil.writeSystemLog(Constant.NOTICE, "系统开始运行垃圾内存回收,内存占用[" + bd_mem1.toString() + "]M");
                    lastGcTime = currTime;


                    System.gc();
                    Thread.sleep(3000);
                    runtime = Runtime.getRuntime();
                    BigDecimal bd_mem2 = new BigDecimal(String.valueOf((runtime.totalMemory()-runtime.freeMemory())/1024.0/1024.0)).setScale(2,BigDecimal.ROUND_HALF_UP);
                    LogUtil.writeSystemLog(Constant.NOTICE, "垃圾内存回收完毕,内存占用[" + bd_mem2.toString() + "]M");
                }

                //进行系统检查
                if ( currTime - lastTime > iPrintFrequencyTime * 1000  )
                {
                    sbOut.append("\n//-------------------------- 监控程序 开始进行检测  ---\n" );
                    //输出线程状态
                    sbOut.append("//------- 开始检测线程情况... \n");
                    checkThreads(iMonitorInfoLevel,sbOut);

                    sbOut.append("//------- 开始检测Map使用情况... \n");
                    checkMap(iMonitorInfoLevel,sbOut);

                    sbOut.append("//------- 开始检测Collection使用情况... \n");
                    checkCollection(iMonitorInfoLevel,sbOut);

                    sbOut.append("//------- 开始检测AFileCacheQueue 使用情况... \n");
                    checkFileCacheQueue(iMonitorInfoLevel,sbOut);

                    sbOut.append("//------- 开始检测CycleQueue 使用情况... \n");
                    checkCycleQueue(iMonitorInfoLevel,sbOut);

                    sbOut.append("//------- 开始检测循环调用情况... \n");
                    checkCycle(iMonitorInfoLevel,sbOut);

                    sbOut.append("//------- 开始检测网络情况... \n");
                    checkNetwork(iMonitorInfoLevel,sbOut);

                    sbOut.append("//------- 开始检测连接情况... \n");
                    checkConnNum(iMonitorInfoLevel,sbOut);

                    sbOut.append("//-------------------------- 监控程序 结束进行检测  ---\n" );
                    LogUtil.writeSystemLog(Constant.INFO, sbOut.toString());

                    //清除相应信息
                    if ( sbOut.length() > 0 )
                        sbOut.delete(0, sbOut.length()-1);

                    sCycles.clear();
                    lastTime = currTime;

                }
            }catch(Exception e)
            {
                LogUtil.WriteLog(Constant.BADLY_ERROR, e);
            }
        }
    }

    //-----------------------------------------  添加相关的监控对象
    /**
     * 添加待监控的Map对象
     * @param sName  名称，须唯一
     * @param map    被监控的Map对象
     */
    public static void addMap(String sName,Map map)
    {
        sMaps.put(sName, map);
    }

    /**
     * 移除被监控的Map对象
     * @param sName 添加监控时使用的名称
     */
    public static void removeMap(String sName)
    {
        sMaps.remove(sName);
    }

    /**
     * 添加待监控的队列
     * @param sName 对列名称，必须唯一
     * @param queue 被监控的对列
     */
    @SuppressWarnings("unchecked")
    public static void addCollection(String sName,Collection queue)
    {
        sCollections.put(sName, queue);
    }

    /**
     * 移除被监控的队列
     * @param sName 添加监控时使用的名称
     */
    public static void removeCollection(String sName)
    {
        sCollections.remove(sName);
    }

    /**
     * 添加待监控的循环队列
     * @param sName 对列名称，必须唯一
     * @param queue 被监控的对列
     */
    public static void addCycleQueue (String sName,CycleQueue<?>  queue )
    {
        sCycleQueues.put(sName, queue);
    }

    /**
     * 移除被监控的循环队列
     * @param sName 添加监控时使用的名称
     */
    public static void removeCycleQueue (String sName)
    {
        sCycleQueues.remove(sName);
    }

    /**
     * 添加待监控的文件队列
     * @param sName 对列名称，必须唯一
     * @param queue 被监控的对列
     */
    public static void addFileCacheQueue (String sName,AFileCacheQueue  queue )
    {
        sFileCacheQueues.put(sName, queue);
    }

    /**
     * 移除被监控的文件队列
     * @param sName 添加监控时使用的名称
     */
    public static void removeFileCacheQueue (String sName)
    {
        sFileCacheQueues.remove(sName);
    }

    /**
     * 添加待监控的线程
     * @param sName 线程名称，必须唯一
     * @param t 被监控的线程
     */
    public static void addThread(String sName,Thread t)
    {
        sThreads.put(sName, t);
    }

    /**
     * 移除被监控的队列
     * @param sName 线程名称，必须唯一
     */
    public static void removeThread(String sName)
    {
        sThreads.remove(sName);
    }

    /**
     * 添加待监控的Socket
     * @param sName 线程名称，必须唯一
     * @param gsc   被监控的Socket
     */
    public static void addSocket(String sName,GessSocketChannel gsc)
    {
        gsc.setStatisticsDataStream(true);
        sSockets.put(sName, gsc);
    }

    /**
     * 添加连接数
     * @param port 端口
     */
    public static synchronized void addConnNum(String port)
    {
        Long total  = null;
        Long curr =  null;
        ConcurrentHashMap<String, Long> temp = sConnNum.get(port);
        if(temp==null)
            temp = new ConcurrentHashMap<String, Long>();

        total = temp.get("TotalNum");
        curr = temp.get("CurrNum");

        if(total == null )
            total = new Long(0);
        if(curr == null)
            curr = new Long(0);

        total = total + 1;
        curr = curr + 1;

        temp.put("TotalNum",total);
        temp.put("CurrNum",curr);

        sConnNum.put(port, temp);
    }

    /**
     * 移除被监控的Socket
     * @param sName 线程名称，必须唯一
     */
    public static void removeSocket(String sName)
    {
        sSockets.remove(sName);
    }

    /**
     * 添加待监控的普通Socket
     * @param sName 线程名称，必须唯一
     * @param socket   被监控的Socket
     */
    public static void addNormalSocket(String sName,Socket socket)
    {
        sNormalSockets.put(sName, socket);
    }

    /**
     * 移除被监控的普通Socket
     * @param sName 线程名称，必须唯一
     */
    public static void removeNormalSocket(String sName)
    {
        sNormalSockets.remove(sName);
    }

    /**
     * 添加循环调用
     * @param sName 循环名称
     */
    public static void addCycleInvoke(String sName)
    {
        if ( bIsRunCycleMonitor )
        {
            Long value = sCycles.get(sName);
            if ( value == null )
            {
                value = 0L;
                sCycles.put(sName, value);
            }
            if ( value.longValue() < Long.MAX_VALUE - 2 )
            {
                value++;
                sCycles.put(sName, value);
            }
        }
    }

    /**
     * 移除循环调用的监控
     * @param sName 被移除的循环名称
     */
    public static void removeCycleInvoke(String sName)
    {
        sCycles.remove(sName);
    }

    /**
     * 移除连接数量
     * @param port
     */
    public static synchronized void subtractConnNum(String port)
    {
        Long curr =  null;
        ConcurrentHashMap<String, Long> temp = sConnNum.get(port);
        if(temp == null)
            return ;

        curr = temp.get("CurrNum");

        if(curr == null)
            curr = new Long(0);

        curr = curr - 1;
        if(curr<0)
            curr = (long)0;

        temp.put("CurrNum",curr);

    }

    //----------------------------------------- 对被监控的对象进行检查

    /** 检查线程信息 */
    public void checkThreads(int level,StringBuilder sbOutResult)
    {

        //获得所有子线程
        Thread[] threads = getAllThreads();

        //输出情况
        for ( int i = 0 ; i < threads.length ; i++ )
        {
            Thread t = threads[i];
            if ( t != null )
            {
                sbOutResult.append("第" + i + "个线程：[" + t.getName() + "," + t.getPriority());
                if ( t.isAlive() )
                    sbOutResult.append(",线程正常]\n");
                else
                    sbOutResult.append(",线程终止]\n");
            }
        }

    }

    /** 获得活动经程 */
    public static Thread[] getAllThreads()
    {
        ThreadGroup tgRoot = null;
        ThreadGroup tgCurr = Thread.currentThread().getThreadGroup();

        //获得根线程组
        while ( tgCurr != null )
        {
            tgRoot = tgCurr;
            tgCurr = tgRoot.getParent();
        }

        //获得所有子线程
        Thread[] threads = new Thread[tgRoot.activeCount() * 2 ];
        tgRoot.enumerate(threads);

        return threads;
    }

    /** 检查Map 信息 */
    public void checkMap(int level,StringBuilder sbOutResult)
    {
        int index = 0;
        Enumeration keys = sMaps.keys();
        while ( keys.hasMoreElements() )
        {
            index++;
            Object objKey = keys.nextElement();
            Map tmpMap = sMaps.get(objKey);
            if ( tmpMap != null )
            {
                sbOutResult.append("第" + index + "个Map:[" + objKey + "," + tmpMap.size() + "]\n");
                if ( level == INFO_LEVEL_DETAIL && tmpMap.size() > 0)
                {
                    sbOutResult.append("-- 明细信息... \n");
                    int subIndex = 0;
                    Iterator<?> it = tmpMap.keySet().iterator();
                    while ( it.hasNext() )
                    {
                        subIndex++;
                        Object subObjKey = it.next();
                        Object subObjValue = tmpMap.get(subObjKey);
                        sbOutResult.append("-- " + subIndex + ":[" + subObjKey + "][" + subObjValue + "]\n");
                    }
                }
            }
        }
    }

    /** 检查Collection 信息 */
    public void checkCollection(int level,StringBuilder sbOutResult)
    {
        int index = 0;
        Enumeration keys = sCollections.keys();
        while ( keys.hasMoreElements() )
        {
            index++;
            Object objKey = keys.nextElement();
            Collection tmpCollection = sCollections.get(objKey);
            if ( tmpCollection != null )
            {
                sbOutResult.append("第" + index + "个Collection:[" + objKey + "," + tmpCollection.size() + "]\n");
                if ( level == INFO_LEVEL_DETAIL && sbOutResult.length() > 0 )
                {
                    sbOutResult.append("-- 明细信息... \n");
                    Object[] objs = tmpCollection.toArray();
                    for ( int i = 0 ; i < objs.length ; i++ )
                    {
                        sbOutResult.append("-- " + i + ":[" + objs[i] + "]\n");
                    }
                }
            }
        }
    }

    /** 检查FileCacheQueue  信息 */
    public void checkFileCacheQueue (int level,StringBuilder sbOutResult)
    {
        int index = 0;
        Enumeration keys = sFileCacheQueues.keys();
        while ( keys.hasMoreElements() )
        {
            index++;
            Object objKey = keys.nextElement();
            AFileCacheQueue tmpFileCacheQueue = sFileCacheQueues.get(objKey);
            if ( tmpFileCacheQueue != null )
            {
                sbOutResult.append("第" + index + "个FileCacheQueue:[" + objKey + "," + tmpFileCacheQueue.getSize() + "]\n");
                if ( level == INFO_LEVEL_DETAIL && sbOutResult.length() > 0 )
                {
                    sbOutResult.append("-- 明细信息... \n");
                }
            }
        }
    }

    /** 检查CycleQueue  信息 */
    public void checkCycleQueue (int level,StringBuilder sbOutResult)
    {
        int index = 0;
        Enumeration keys = sCycleQueues.keys();
        while ( keys.hasMoreElements() )
        {
            index++;
            Object objKey = keys.nextElement();
            CycleQueue<?> tmpCycleQueue = sCycleQueues.get(objKey);
            if ( tmpCycleQueue != null )
            {
                sbOutResult.append("第" + index + "个CycleQueue:[" + objKey + "," + tmpCycleQueue.count() + "]\n");
                if ( level == INFO_LEVEL_DETAIL && sbOutResult.length() > 0 )
                {
                    sbOutResult.append("-- 明细信息... \n");
                }
            }
        }
    }

    /** 检查 循环 */
    public void checkCycle(int level,StringBuilder sbOutResult)
    {
        int index = 0;
        Enumeration<String> keys = sCycles.keys();
        while ( keys.hasMoreElements() )
        {
            index++;
            Object objKey = keys.nextElement();
            Long num = sCycles.get(objKey);
            if ( num != null )
                sbOutResult.append("第" + index + "个Cycle:[" + objKey + "][" + (currTime - lastTime )/1000 + "秒调用" + num.longValue() + "次]\n");
        }
    }

    /** 检测 网络流量 */
    public void checkNetwork(int level,StringBuilder sbOutResult)
    {
        int index = 0;
        Enumeration<String> keys = sSockets.keys();
        while ( keys.hasMoreElements() )
        {
            index++;
            Object objKey = keys.nextElement();
            GessSocketChannel gsc = sSockets.get(objKey);
            if ( gsc != null )
                sbOutResult.append("第" + index + "个Socket:[" + gsc.toString()+ "]\n");
        }

    }

    //-------------------------获得被监控的对象集合

    public static ConcurrentHashMap<String,Map> getMaps()
    {
        return sMaps;
    }

    public static ConcurrentHashMap<String,Collection> getCollections()
    {
        return sCollections;
    }

    public static ConcurrentHashMap<String,AFileCacheQueue> getFileCacheQueues()
    {
        return sFileCacheQueues;
    }

    public static ConcurrentHashMap<String,Long> getCycles()
    {
        return sCycles;
    }

    public static ConcurrentHashMap<String,Thread> getThreads()
    {
        return sThreads;
    }

    public static ConcurrentHashMap<String,GessSocketChannel> getSockets()
    {
        return sSockets;
    }

    public static ConcurrentHashMap<String,Socket> getNormalSockets()
    {
        return sNormalSockets ;
    }

    public static long getCycleInvokeTime()
    {
        return (currTime - lastTime )/1000 ;
    }

    public static ConcurrentHashMap<String, Long> getConnNum(String port)
    {
        return sConnNum.get(port);
    }

    public static ConcurrentHashMap<String,CycleQueue<?>> getCycleQueues()
    {
        return sCycleQueues;
    }

    public static ConcurrentHashMap<String,ConcurrentHashMap<String, Long>> getConnNum()
    {
        return sConnNum;
    }

    public static long getStartTime()
    {
        return startTime;
    }

    /**
     * 清除连接数量
     */
    public static synchronized void clearConnNum(String port)
    {
        sConnNum.remove(port);
    }


    /**
     * 检查连接数量
     * @param level
     * @param sbOutResult
     */
    public static void checkConnNum(int level,StringBuilder sbOutResult)
    {
        int index = 0;
        Enumeration keys = sConnNum.keys();
        while ( keys.hasMoreElements() )
        {
            index++;
            String key = (String) keys.nextElement();
            ConcurrentHashMap<String, Long> temp = sConnNum.get(key);
            sbOutResult.append("第" + index + "个端口["+key+"]连接信息\n");
            long total = temp.get("TotalNum") == null ? 0 : temp.get("TotalNum");
            long curr = temp.get("CurrNum") == null ? 0 : temp.get("CurrNum");
            sbOutResult.append("总连接数："+total+"，当前连接数："+curr+"\n");
        }

    }

    /**
     * 关闭监控程序
     */
    public void close()
    {
        bIsRun = false;
    }


    public ConnNumInfo buildConnNumInfo() {

        ConnNumInfo connNumInfo = new ConnNumInfo();
        ConcurrentHashMap<String,ConcurrentHashMap<String, Long>> sConnNum = getConnNum();
        int index = 0;
        Enumeration<String> keys = sConnNum.keys();
        while ( keys.hasMoreElements() )
        {
            index++;
            String key = (String) keys.nextElement();
            ConcurrentHashMap<String, Long> temp = sConnNum.get(key);
            long total = temp.get("TotalNum") == null ? 0 : temp.get("TotalNum");
            long curr = temp.get("CurrNum") == null ? 0 : temp.get("CurrNum");
            ConnNumInfo.ConnNumDetailInfo detail = connNumInfo.new ConnNumDetailInfo(key, total, curr);
            connNumInfo.getDetails().add(detail);
        }
        return connNumInfo;
    }


    public DbConnPoolInfo buildDbConnPoolInfo() {

        DbConnPoolInfo dbConnPoolInfo = new DbConnPoolInfo();

        Iterator<String> it = ConnManager.htPool.keySet().iterator();
        while(it.hasNext())
        {
            String key = it.next();
            ConnPool pool = ConnManager.htPool.get(key);
            DbConnPoolInfo.DbConnPoolDetail detail = dbConnPoolInfo.new DbConnPoolDetail(key, pool.getPoolSize(), pool.getUseCount(), pool.getFreeCount());
            dbConnPoolInfo.getDbConnPoolDetail().add(detail);
        }
        return dbConnPoolInfo;
    }


    public DiskInfo buildDiskInfo() {
        return new DiskInfo();
    }


    public MapInfo buildMapInfo() {

        MapInfo mapInfo = new MapInfo();

        Enumeration<?> keys = getMaps().keys();
        while ( keys.hasMoreElements() )
        {
            Object objKey = keys.nextElement();
            Map<?, ?> tmpMap = MonitorThread.getMaps().get(objKey);
            MapInfo.MapDetail detail = mapInfo.new MapDetail(objKey.toString(), tmpMap.size());
            mapInfo.getMapDetail().add(detail);
        }

        Enumeration<?> cKeys = MonitorThread.getCollections().keys();
        while ( cKeys.hasMoreElements() )
        {
            Object objKey = cKeys.nextElement();
            Collection<?> tmpCollection = MonitorThread.getCollections().get(objKey);
            MapInfo.MapDetail detail = mapInfo.new MapDetail(objKey.toString(), tmpCollection.size());
            mapInfo.getMapDetail().add(detail);
        }
        return mapInfo;
    }


    public MemoryInfo buildMemoryInfo() {
        return new MemoryInfo();
    }


    public QueueInfo buildQueueInfo() {

        QueueInfo queueInfo = new QueueInfo();

        Iterator<String> it = getFileCacheQueues().keySet().iterator();
        while(it.hasNext())
        {
            String key = it.next();
            int size = MonitorThread.getFileCacheQueues().get(key).getSize();
            QueueInfo.QueueDetail detail = queueInfo.new QueueDetail(key, size);
            queueInfo.getQueueDetail().add(detail);
        }

        it = MonitorThread.getCycleQueues().keySet().iterator();
        while(it.hasNext())
        {
            String key = it.next();
            int size = MonitorThread.getCycleQueues().get(key).count();
            QueueInfo.QueueDetail detail = queueInfo.new QueueDetail(key, size);
            queueInfo.getQueueDetail().add(detail);
        }
        return queueInfo;
    }


    public SocketInfo buildSocketInfo() {

        SocketInfo socketInfo = new SocketInfo();

        Enumeration<?> keys = getSockets().keys();
        while ( keys.hasMoreElements() )
        {
            Object objKey = keys.nextElement();
            GessSocketChannel tmpSocket = MonitorThread.getSockets().get(objKey);
            SocketInfo.SocketDetail detail = socketInfo.new SocketDetail(tmpSocket);
            socketInfo.getSocketDetail().add(detail);
        }
        return socketInfo;
    }


    public StartInfo buildStartInfo() {
        StartInfo  startInfo = new StartInfo();
        startInfo.setStartTime(MonitorThread.getStartTime());
        return startInfo;
    }


    public ThreadInfo buildThreadInfo() {
        ThreadInfo threadInfo = new ThreadInfo();
        Thread[] threads = getAllThreads();

        int alive = 0;
        for(Thread thread : threads)
        {
            if(thread!=null)
            {
                if(thread.isAlive())
                    alive ++ ;
            }
        }
        threadInfo.setTotal(threads.length);
        threadInfo.setAlive(alive);
        return threadInfo;
    }

}
